package cn.kmsoft.jssc.controller;

import cn.kmsoft.common.ResultEnum;
import cn.kmsoft.jssc.config.RabbitMqConfig;
import cn.kmsoft.jssc.config.TdlyfldmConfig;
import cn.kmsoft.jssc.entity.analyse.AnalyseDb;
import cn.kmsoft.jssc.entity.analyse.AnalysePoint;
import cn.kmsoft.jssc.entity.analyse.AnalyseTable;
import cn.kmsoft.jssc.entity.mq.JsscMqMessage;
import cn.kmsoft.jssc.entity.mq.MqMessage;
import cn.kmsoft.jssc.util.RedisUtils;
import cn.kmsoft.common.ResInfo;
import cn.kmsoft.stgeometry.util.CrsUtil;
import cn.kmsoft.stgeometry.util.JTSGeometryWKTUtil;
import cn.kmsoft.wololo.object.query.AnalysisType;
import cn.kmsoft.stgeometry.util.GeoJsonQueryUtil;
import cn.kmsoft.stgeometry.util.Shapefile2GeoJson;
import cn.kmsoft.wololo.object.query.GeoJsonQuery;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.MDC;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;

@Slf4j
@CrossOrigin
@RestController
@Api(description = "Hello服务调用", tags = "0-HelloController")
@RequestMapping(value = "/hello")
public class HelloController extends BaseController {
    //private static final Log logger = LogFactory.getLog(HelloController.class);
    private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss-SSS");
    public static final String TASK_ID = "TASK_ID";

    @Autowired
    private RedisUtils redisUtil;

    @Autowired
    private AmqpTemplate rabbitTemplate;//rabbitmq消息队列


    @ApiOperation(value = "test", notes = "test")
    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public ResInfo test() {
        MDC.put(TASK_ID, UUID.randomUUID().toString());
        ResInfo resInfo = new ResInfo();

        //起始时间
        Date dateNow = new Date();
        String dateNowStr = sdf.format(dateNow);
        String msgContent = String.format("--->hello test,time: %s",dateNowStr);
        System.out.println(msgContent);
        log.info(msgContent);

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("test,ok");
        resInfo.setData(msgContent);
        resInfo.setRes(msgContent);

        //MDC快速入门示例
        MDC.remove(TASK_ID);

        return resInfo;
    }

    @ApiOperation(value = "testConfigs", notes = "testConfigs")
    @RequestMapping(value = "/testConfigs", method = RequestMethod.GET)
    public ResInfo testConfigs(int code) {
        ResInfo resInfo = new ResInfo();

        Date dateNow = new Date();
        String dateNowStr = sdf.format(dateNow);
        String msgContent = String.format("--->testConfigs,time: %s",dateNowStr);
        System.out.println(msgContent);
        log.info(msgContent);

        //后台console输出
        System.out.println();
        System.out.println(String.format("--->0-analystTypes"));
        //String analystServer = this.analyseConfig.getServerUrl();

        //分析类型
        Map<String,String> analystTypes = this.analyseConfig.getAnalystTypes();
        for (Map.Entry<String,String> ent: analystTypes.entrySet()){
            String typepoint = ent.getKey();
            String typename = ent.getValue();
            System.out.println(String.format("--->typepoint: %s, typename: %s ",typepoint, typename));
        }

        System.out.println();
        System.out.println(String.format("--->1.analyseDbs"));
        List<AnalyseDb> analyseDbs = this.analyseConfig.getAnalyseDbs();
        for (AnalyseDb analyseDb: analyseDbs){
            System.out.println(analyseDb);
        }

        System.out.println();
        System.out.println(String.format("--->2.analysePoints"));
        List<AnalysePoint> analysePoints = this.analyseConfig.getAnalysePoints();
        for (AnalysePoint analysePoint: analysePoints){
            System.out.println(analysePoint);
        }

        System.out.println();
        System.out.println(String.format("--->3.analyseTables"));
        List<AnalyseTable> analyseTables = this.analyseConfig.getAnalyseTables();
        for (AnalyseTable analysePoint: analyseTables){
            System.out.println(analysePoint);
        }

        System.out.println();
        Map<String,String> tdlyxzfldm = this.analyseConfig.getTdlyxzfldm();
        for (Map.Entry<String,String> ent: tdlyxzfldm.entrySet()){
            System.out.println(String.format("---> %s : %s ",ent.getKey(),ent.getValue()));
        }
        System.out.println();
        Map<String,String> tdghfldm = this.analyseConfig.getTdghytfldm();
        for (Map.Entry<String,String> ent: tdghfldm.entrySet()){
            System.out.println(String.format("--->%s : %s ",ent.getKey(),ent.getValue()));
        }
        System.out.println();
        Map<String,String> tdlyxzfldm_sd = this.analyseConfig.getTdlyxzfldm_sd();
        for (Map.Entry<String,String> ent: tdlyxzfldm_sd.entrySet()){
            System.out.println(String.format("--->%s : %s ",ent.getKey(),ent.getValue()));
        }

        System.out.println("--->TdlyfldmConfig ggglyfwyd_sd test: ");
        TdlyfldmConfig tdlyfldmConfig = this.analyseConfig.getTdlyfldmConfig();
        Set<String> ss= tdlyfldmConfig.getTdlyxzfldm_ggglyfwyd_sd();
        for(String s: ss){
            System.out.println(s);
        }

        //输出配置数据
        int size=0;
        String msg="";
        switch (code){
            case 1:{
                //analyseDbs
                size= analyseDbs.size();
                msg= String.format("--->testConfigs, analyseDbs, size: %d",size);
                resInfo.setData(analyseDbs);
                break;
            }
            case 2:{
                //analysePoints
                size= analysePoints.size();
                msg= String.format("--->testConfigs, analysePoints, size: %d",size);
                resInfo.setData(analysePoints);
                break;
            }
            case 3:{
                //analyseTables
                size= analyseTables.size();
                msg= String.format("--->testConfigs, analyseTables, size: %d",size);
                resInfo.setData(analyseTables);
                break;
            }
            default:
                size=0;
        }

        resInfo.setMsg(msg);
        resInfo.setCode(200);
        resInfo.setStatus(ResInfo.SUCCESS);

        return resInfo;
    }


    @ApiOperation(value = "geoJsonTest", notes = "获取默认geoJson对象测试")
    @RequestMapping(value = "/geoJsonTest", method= RequestMethod.GET)
    public ResInfo geoJsonTest(){
        ResInfo resInfo = new ResInfo();

        //3-shp2geojson
        String shppath = this.analyseConfig.getTestshppath();
        File shpfile= new File(shppath);
        if(!shpfile.exists()){
            String msg= String.format("--->默认shppath路径对应的shp文件不存在, shppath: %s",shppath);
            System.out.println(msg);
            log.error(msg);

            resInfo.setStatus(ResultEnum.VALIDATE_FAILED.getStatus());
            resInfo.setCode(ResultEnum.VALIDATE_FAILED.getCode());
            resInfo.setMsg("geoJsonTest stop! ");
            return resInfo;
        }

        String geoJsonStr = Shapefile2GeoJson.shp2GeoJsonStr(shppath);
        //GeoJson geojson= Shapefile2GeoJson.shp2GeoJson(shppath);
        System.out.println();
        System.out.println(geoJsonStr);

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("geoJsonTest success! ");
        resInfo.setRes(geoJsonStr);

        return resInfo;
    }


    @ApiOperation(value = "geoJsonQueryTestForSpatialAnalyst", notes = "获取默认geoJsonQuery对象测试")
    @RequestMapping(value = "/geoJsonQueryTestForSpatialAnalyst", method= RequestMethod.GET)
    public ResInfo geoJsonQueryTestForSpatialAnalyst(){
        ResInfo resInfo = new ResInfo();

        //3-shp2geoquery
        int wkid = 4524;
        //String shppath = "E:\\temp\\jssc\\500155梁平区\\01空间数据\\用地红线范围.shp";
        String shppath = this.analyseConfig.getTestshppath();
        File shpfile= new File(shppath);
        if(!shpfile.exists()){
            String msg= String.format("--->默认shppath路径对应的shp文件不存在, shppath: %s",shppath);
            System.out.println(msg);
            log.error(msg);

            resInfo.setStatus(ResultEnum.VALIDATE_FAILED.getStatus());
            resInfo.setCode(ResultEnum.VALIDATE_FAILED.getCode());
            resInfo.setMsg("geoJsonQueryTestForSpatialAnalyst stop! ");
            return resInfo;
        }

        try {
            String crsName = JTSGeometryWKTUtil.getShpCrsName(shppath);
            String wkidStr= CrsUtil.getWkidByCrsName(crsName);
            wkid = Integer.parseInt(wkidStr);
        } catch (Exception ex) {
            String detailMsg = ex.getMessage();
            String msgContent = String.format("--->geoJsonQueryTestForSpatialAnalyst error, detailMsg: %s",detailMsg);
            System.out.println(msgContent);
            log.info(msgContent);
        }
        //String geoQueryStr = GeoJsonQueryUtil.shp2GeoQueryStr(shppath, wkid);
        GeoJsonQuery geoJsonQuery = GeoJsonQueryUtil.shp2GeoQuery(shppath, wkid, AnalysisType.INTERSECT);
        //GeoJsonQuery2 geoJsonQuery2 = GeoJsonQueryUtil.shp2GeoQuery2(shppath, wkid);
        System.out.println();
        System.out.println(JSON.toJSONString(geoJsonQuery));

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("geoJsonQueryTestForSpatialAnalyst success! ");
        resInfo.setRes(geoJsonQuery);

        return resInfo;
    }

    @ApiOperation(value = "geoJsonQueryTestForSpatialQuery", notes = "获取默认geoJsonQuery对象测试")
    @RequestMapping(value = "/geoJsonQueryTestForSpatialQuery", method= RequestMethod.GET)
    public ResInfo geoJsonQueryTestForSpatialQuery(){
        ResInfo resInfo = new ResInfo();

        //3-shp2geoquery
        int wkid = 4524;
        //String shppath = "E:\\temp\\jssc\\500155梁平区\\01空间数据\\用地红线范围.shp";
        String shppath = this.analyseConfig.getTestshppath();
        File shpfile= new File(shppath);
        if(!shpfile.exists()){
            String msg= String.format("--->默认shppath路径对应的shp文件不存在, shppath: %s",shppath);
            System.out.println(msg);
            log.error(msg);

            resInfo.setStatus(ResultEnum.VALIDATE_FAILED.getStatus());
            resInfo.setCode(ResultEnum.VALIDATE_FAILED.getCode());
            resInfo.setMsg("geoJsonQueryTestForSpatialQuery stop! ");
            return resInfo;
        }

        try {
            String crsName = JTSGeometryWKTUtil.getShpCrsName(shppath);
            String wkidStr= CrsUtil.getWkidByCrsName(crsName);
            wkid = Integer.parseInt(wkidStr);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        //String geoQueryStr = GeoJsonQueryUtil.shp2GeoQueryStr(shppath, wkid);
        GeoJsonQuery geoJsonQuery = GeoJsonQueryUtil.shp2GeoQuery(shppath, wkid, AnalysisType.SPATIALQUERY);
        //GeoJsonQuery2 geoJsonQuery2 = GeoJsonQueryUtil.shp2GeoQuery2(shppath, wkid);
        System.out.println();
        System.out.println(JSON.toJSONString(geoJsonQuery));

        resInfo.setStatus(ResInfo.SUCCESS);
        resInfo.setCode(200);
        resInfo.setMsg("shp2GeoQuery success! ");
        resInfo.setRes(geoJsonQuery);

        return resInfo;
    }

    @ApiOperation(value = "redisTest", notes = "开展redis测试")
    @RequestMapping(value = "/redisTest", method= RequestMethod.GET)
    public ResInfo redisTest() {
        ResInfo resInfo = new ResInfo();

        Date dateNow= new Date();
        String dateNowStr = sdf.format(dateNow).toString();

        String key = "jssc.time";
        redisUtil.set(key,dateNowStr);

        resInfo.setRes(redisUtil.get(key));
        resInfo.setCode(200);
        resInfo.setStatus(ResInfo.SUCCESS);

        return resInfo;
    }

    @ApiOperation(value = "rabbitmqPingTest", notes = "开展rabbitmq ping测试")
    @RequestMapping(value = "/rabbitmqPingTest", method= RequestMethod.GET)
    public ResInfo rabbitmqPingTest() {
        ResInfo resInfo = new ResInfo();

        Date dateNow= new Date();
        String dateNowStr = sdf.format(dateNow).toString();
        String jobId = String.valueOf("rabbitmq-detectQuartzJob");
        String detailMsg = "";

        try {
            //发送消息到消息对比中
            String result = sendMqPingTest(jobId);

            String msg=String.format("--->调用sendMqPingTest成功, jobId: %s, time: %s", jobId, dateNowStr);
            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setMsg(msg);
            resInfo.setCode(ResultEnum.SUCCESS.getCode());
            resInfo.setData(result);

            detailMsg= msg;
        }catch (Exception ex){
            String result = ex.getMessage();
            String msg =String.format("--->调用sendMqPingTest失败, jobId: %s, time: %s",jobId, dateNowStr);

            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setMsg(msg);
            resInfo.setCode(ResultEnum.COMMON_FAILED.getCode());
            resInfo.setData(result);

            detailMsg= msg;
        }
        log.info(detailMsg);

        return resInfo;
    }


    @ApiOperation(value = "rabbitmqTest", notes = "开展rabbitmq测试")
    @RequestMapping(value = "/rabbitmqTest", method= RequestMethod.GET)
    public ResInfo rabbitmqTest(String msgStr) {
        ResInfo resInfo = new ResInfo();

        Date dateNow= new Date();
        String dateNowStr = sdf.format(dateNow).toString();
        String jobId = String.valueOf("rabbitmq-detectQuartzJob");
        String detailMsg = "";

        try {
            //发送消息到消息对比中
            String result = sendMqTest(msgStr);

            resInfo.setStatus(ResInfo.SUCCESS);
            resInfo.setMsg(result);
            resInfo.setCode(ResultEnum.SUCCESS.getCode());
            resInfo.setData(result);

            detailMsg= result;
        }catch (Exception ex){
            String result = ex.getMessage();
            String msg =String.format("--->调用sendMqTest失败, jobId: %s, time: %s",jobId, dateNowStr);

            resInfo.setStatus(ResInfo.FAIL);
            resInfo.setMsg(msg);
            resInfo.setCode(ResultEnum.COMMON_FAILED.getCode());
            resInfo.setData(result);

            detailMsg= msg;
        }
        log.info(detailMsg);

        return resInfo;
    }

    /**
     * 消息队列测试
     *
     * @param sendMqMsg
     */
    public String sendMqTest(String sendMqMsg ) {
        //int millSecond= 60*60;
        //消息属性
        MessageProperties mqMsgProps = new MessageProperties();
        mqMsgProps.setExpiration(String.valueOf(RabbitMqConfig.RMQExpirationMillSecond));

        String jobId = UUID.randomUUID().toString();
        String startMsg = String.format("--->sendMqTest start, jobId:%s, sendMqMsg: %s",jobId,sendMqMsg);
        System.out.println();
        System.out.println(startMsg);

        //消息体
        JsscMqMessage mqMessage = new JsscMqMessage();
        mqMessage.setHostId("java host01");
        mqMessage.setJobId(jobId);
        mqMessage.setOperationCode(JsscMqMessage.OPERCODE_RABBITMQ_TEST);
        mqMessage.setOperationName("OPERCODE_RABBITMQ_TEST");
        mqMessage.setMsgContent(sendMqMsg);

        //JSONObject msg =  JSON.parseObject(JSON.toJSONString(mqMessage));
        String jsonStr = JSON.toJSONString(mqMessage);
        Message message = new Message(jsonStr.getBytes(), mqMsgProps);
        //三个两个参数：交换机,路由键和消息体
        this.rabbitTemplate.convertAndSend(RabbitMqConfig.TOPIC_EXCHANGE_JSSC, RabbitMqConfig.JAVA2ARCPY_JSSC_ROUTINGKEY, jsonStr);

        String finishMsg = String.format("--->sendMqTest finished, jobId:%s, sendMqMsg: %s", jobId, sendMqMsg);
        //System.out.println(finishMsg);

        return finishMsg;
    }

    /**
     * 消息队列ping测试
     *
     * @param jobId
     */
    public String sendMqPingTest(String jobId ) {
        //int millSecond= 60*60;
        //消息属性
        MessageProperties mqMsgProps = new MessageProperties();
        mqMsgProps.setExpiration(String.valueOf(RabbitMqConfig.RMQExpirationMillSecond));

        System.out.println();
        System.out.println(String.format("--->sendMqTest start, jobId:%s",jobId ));
        //消息体
        JsscMqMessage mqMessage = new JsscMqMessage();
        mqMessage.setHostId("java host01");
        mqMessage.setJobId(jobId);
        mqMessage.setOperationCode(JsscMqMessage.OPERCODE_RABBITMQ_TEST);
        mqMessage.setOperationName("OPERCODE_RABBITMQ_TEST");
        mqMessage.setMsgContent("rabbitmq ping test");

        //JSONObject msg =  JSON.parseObject(JSON.toJSONString(mqMessage));
        String jsonStr = JSON.toJSONString(mqMessage);
        Message message = new Message(jsonStr.getBytes(), mqMsgProps);
        //三个两个参数：交换机,路由键和消息体
        this.rabbitTemplate.convertAndSend(RabbitMqConfig.TOPIC_EXCHANGE_JSSC, RabbitMqConfig.JAVA2ARCPY_JSSC_ROUTINGKEY, jsonStr);

        String msgStr = String.format("--->sendMqTest finished, jobId:%s", jobId);
        System.out.println(msgStr);

        return msgStr;
    }

}